// Copyright 2022 The Molego Authors. All rights reserved.
// Use of this source code is governed by a BSD-style
// license that can be found in the LICENSE file.

package translate

import (
	. "gitee.com/west0207/molego/core/log"
	utils "gitee.com/west0207/molego/core/utils"

	etree "gitee.com/west0207/etree"
)

// 获取变更表字段类型的Entity标签的sql语句
// dbmsName *string 数据库类型名称，例如：mysql
// dbmsVersion *string 数据库系统版本，例如：5
// modifyDataTypeEle *etree.Element 变更表字段类型的Entity标签
func GetModifyDataTypeSql(dbmsName *string, dbmsVersion *string, modifyDataTypeEle *etree.Element) (string, error) {
	return getDefaultModifyDataTypeSql(dbmsName, dbmsVersion, modifyDataTypeEle)
}

// <modifyDataType columnName="org_id" newDataType="integer" tableName="test_t04"/>
// 如下仅适用于PostgreSQL
// alter table test_column_type alter column type_numeric type decimal(15,2) using type_numeric::decimal;
// 如下仅适用于MySQL，该操作带有副作用，会删除该字段的默认值以及注释
// alter table test_t04 modify column update_user integer
// 如下仅适用于Oracle
// alter table base_module modify parent_id varchar2(40);
// sqlite数据库不支持变更表字段类型操作modifyDataType
func getDefaultModifyDataTypeSql(dbmsName *string, dbmsVersion *string, modifyDataTypeEle *etree.Element) (string, error) {
	tableName := modifyDataTypeEle.SelectAttrValue("tableName", utils.EMPTY)
	SetPropertyValue(dbmsName, &tableName)

	if *dbmsName == "sqlite" {
		Sug.Errorf("sqlite数据库不支持变更表字段类型操作modifyDataType: %v", tableName)
		return "-- SQLite database does not support the operation of changing table field type" + utils.LF, nil
	}

	columnName := modifyDataTypeEle.SelectAttrValue("columnName", utils.EMPTY)
	SetPropertyValue(dbmsName, &columnName)
	ctype := modifyDataTypeEle.SelectAttrValue("newDataType", utils.EMPTY)
	SetPropertyValue(dbmsName, &ctype)
	SetColumnType(dbmsName, &ctype)

	switch *dbmsName {
	case MySQL, TiDB:
		// alter table test_t04 modify column update_user integer;
		sql := "alter table " + tableName + " modify column " + columnName + utils.SPACE + ctype + utils.SEMICOLON + utils.LF
		return sql, nil
	case PostgreSQL:
		// alter table test_column_type alter column type_numeric type decimal(15,2) using type_numeric::decimal;
		typeKey := GetColumnTypeKey(&ctype)
		sql := "alter table " + tableName + " alter column " + columnName + " type " + ctype + " using " + columnName + "::" + typeKey + utils.SEMICOLON + utils.LF
		return sql, nil
	case Kingbase:
		// alter table test_column_type alter column type_numeric type decimal(15,2);
		sql := "alter table " + tableName + " alter column " + columnName + " type " + ctype + utils.SEMICOLON + utils.LF
		return sql, nil
	case MsSQLServer:
		// alter table test_column_type alter column type_numeric decimal(5, 2);
		sql := "alter table " + tableName + " alter column " + columnName + utils.SPACE + ctype + utils.SEMICOLON + utils.LF
		return sql, nil
	case Oracle:
		// alter table base_module modify parent_id varchar2(40);
		sql := "alter table " + tableName + " modify " + columnName + utils.SPACE + ctype + utils.SEMICOLON + utils.LF
		return sql, nil
	default:
		// same to oracle
		// alter table base_module modify parent_id varchar2(40);
		sql := "alter table " + tableName + " modify " + columnName + utils.SPACE + ctype + utils.SEMICOLON + utils.LF
		return sql, nil
	}
}
